import os
import base64
import datetime
from typing import Union
from apis import api_routes
from flask import abort, g, request, jsonify
from models.facility.facility import Facility
from models.users.users import Users
from security.decoration import certification
from sqlalchemy import text
from sqlalchemy import desc
from security.security import encode_jwt
from public.local import datetime_type
from security.security import decode_jwt
from models.facility.upkeep import Upkeep
from public.contexts import context_logs


@api_routes.route("/upkeep/init", methods=["GET"])
@certification(auth=True, role=None)
def func_upkeep_init_get_api():
    """
    查询上次记录下次保养内容, 只要有token 都可以访问 完成API开发
    http://127.0.0.1:8080/api/upkeep/init
    Content-Type=application/x-www-form-urlencoded
    methods=["GET"]
    {
    "facility_id"   int      ****  设备ID
    }
    :return:
        {'status': 400, 'data': data}
    ---
    tags:
      - 易损件管理
    """
    ft_id: int = request.args.get("facility_id", default=0, type=int)
    upkeep: Union[Upkeep, None] = g.session.query(Upkeep).filter(
                                    Upkeep.facility_id == ft_id
                                ).order_by(desc(Upkeep.id)).limit(1).offset(0).first()
    message: Union[str, None] = None
    if upkeep is not None:
        message = upkeep.data
    return jsonify({'status': 200, 'data': message})


@api_routes.route("/upkeep", methods=["POST"])
@certification(auth=True, role=None)
def func_upkeep_post_api():
    """
    设备保养记录添加, 只要有token 都可以访问 完成API开发
    http://127.0.0.1:8080/api/upkeep
    Content-Type=multipart/form-data
    methods=["POST"]
    {
    "facility_id"     int        ****    设备ID
    "operate"         string     ****    这次保养日期  格式 YYYY-MM-DD
    "note"            string     ****    保养记录日志, 初始化数据从 （/api/upkeep/init GET）拿
    "image"           file               保养拍照保存照片
    "data"            string     ****    下次设备保养内容
    "remind"          string     ****    下次保养日期   格式 YYYY-MM-DD
    }
    :return:
        {'status': 4000, 'msg': "没有查询到保养设备"}
        {'status': 4001, 'msg': "文件类型错误"}
        {'status': 200, 'msg': "设备保养记录成功"}
    ---
    tags:
      - 易损件管理
    """
    facility_id = request.form.get("facility_id")
    operate = request.form.get("operate")
    note0 = request.form.get("note")
    image = request.files.get("image")
    note1 = request.form.get("data")
    remind = request.form.get("remind")

    if not all([facility_id, operate, note0, note1, remind]):
        abort(400)

    facility: Union[Facility, None] = g.session.query(Facility).filter(Facility.id == facility_id).first()
    if facility is None:
        return jsonify({'status': 4000, 'msg': "没有查询到保养设备"})

    data = None
    if image is not None:
        data_name = image.filename
        data = image.read()
        if os.path.splitext(data_name)[-1].lower() not in [".png", ".jpg", ".jpeg"]:
            return jsonify({'status': 4001, 'msg': "文件类型错误"})

    operate1 = datetime.datetime.strptime(operate, "%Y-%m-%d")
    remind1 = datetime.datetime.strptime(remind, "%Y-%m-%d")
    user_id: int = decode_jwt(g.token)["user_id"]

    context_logs(name="设备保养记录添加", obsolescence=None, data=None)

    g.session.add(Upkeep(
        facility_id=facility_id, operate=operate1,
        note=note0, image=data, data=note1, remind=remind1, user_id=user_id
    ))
    g.session.commit()
    return jsonify({'status': 200, 'msg': "设备保养记录成功"})


@api_routes.route("/upkeep", methods=["GET"])
@certification(auth=True, role=None)
def func_upkeep_get_api():
    """
    设备保养记录查询, 只要有token 都可以访问 完成API开发
    http://127.0.0.1:8080/api/upkeep
    Content-Type=application/x-www-form-urlencoded
    methods=["GET"]
    {
    "index"         int      ****  第几页，默认为1
    "size"          int      ****  每页数据多少, 默认每页10条数据
    "facility_id"   int            设备ID

    }
    :return:
        {'status': 400, 'data': data}
    ---
    tags:
      - 易损件管理
    """
    index: int = request.args.get("index", default=1, type=int)
    size: int = request.args.get("size", default=10, type=int)
    ft_id: int = request.args.get("facility_id", default=0, type=int)

    count: int = 0
    if ft_id > 0:
        count = g.session.query(Upkeep.id).filter(Facility.id == ft_id).count()
    else:
        count = g.session.query(Upkeep.id).count()
    page: int = int((count / size) + 1) if (count / size) > int(count / size) else int(count / size)

    sql = """
        SELECT 
            upkeep.id, to_char(upkeep.operate,'YYYY-MM-DD'), 
            upkeep.note, upkeep.image, to_char(upkeep.remind,'YYYY-MM-DD'),
            facility.serials, facility.name, users.account, users.name, upkeep.data
        FROM upkeep INNER JOIN facility ON upkeep.facility_id = facility.id
        INNER JOIN users on upkeep.user_id = users.id {} ORDER BY upkeep.id DESC LIMIT :arg1 OFFSET :arg2
    """
    res: list = []
    sql = sql.format("WHERE facility.id = :fid") if ft_id else sql.format("")
    data = g.session.execute(text(sql), {"arg1": size, "arg2": ((index - 1) * size), "fid": ft_id}).fetchall()

    for index, itr in enumerate(data):
        image = base64.b64encode(itr[3]).decode('utf-8') if itr[3] else None
        res.append({
            "upkeep_id": itr[0], "operate": itr[1], "note": itr[2], "image": image, "data": itr[9],
            "remind": itr[4], "serials": itr[5], "name": itr[6], "account": itr[7], "account_name": itr[8]
        })

    doc: dict = {
        "upkeep_id": "数据库ID", "operate": "本次保养时间", "note": "保养记录", "image": "照片", "data": "下次设备保养内容",
        "remind": "下次保养日期", "serials": "设备编号", "name": "设备名", "account": "保养账户", "account_name": "保养姓名"
    }
    return jsonify({'status': 200, 'data': res, "index": index, "size": size, "page": page, "count": count, "doc": doc})


@api_routes.route("/upkeep", methods=["PUT"])
@certification(auth=True, role=None)
def func_upkeep_put_api():
    """
    设备保养记录修改, 只要有token 都可以访问，完成API开发
    http://127.0.0.1:8080/api/upkeep
    Content-Type=multipart/form-data
    methods=["PUT"]
    {
    "upkeep_id"       int            ****   数据库ID
    "operate"         string         这次保养日期  格式 YYYY-MM-DD
    "note"            string         保养记录日志
    "image"           file           保养拍照保存照片
    "data"            string         下次设备保养内容
    "remind"          string         下次保养日期   格式 YYYY-MM-DD
    }
    :return:
        {'status': 4000, 'msg': "没有查询到保养记录"})
        {'status': 4001, 'msg': "文件类型错误"}
        {'status': 200, 'msg': "设备保养记录修改成功"}
    ---
    tags:
      - 易损件管理
    """
    upkeep_id = request.form.get("upkeep_id")
    operate = request.form.get("operate")
    note0 = request.form.get("note")
    image = request.files.get("image")
    note1 = request.form.get("data")
    remind = request.form.get("remind")
    if upkeep_id is None:
        abort(400)
    uk: Union[Upkeep, None] = g.session.query(Upkeep).filter(Upkeep.id == upkeep_id).first()
    if uk is None:
        return jsonify({'status': 4000, 'msg': "没有查询到保养记录"})

    if image is not None:
        data_name = image.filename
        data: bytes = image.read()
        if os.path.splitext(data_name)[-1].lower() not in [".png", ".jpg", ".jpeg"]:
            return jsonify({'status': 4001, 'msg': "文件类型错误"})
        uk.image = data
    if operate is not None:
        uk.operate = datetime.datetime.strptime(operate, "%Y-%m-%d")

    if remind is not None:
        uk.remind = datetime.datetime.strptime(remind, "%Y-%m-%d")

    if note0 is not None and note0 != uk.note:
        uk.note = note0

    if note1 is not None and note1 != uk.data:
        uk.data = note1
    g.session.commit()
    return jsonify({'status': 200, 'msg': "设备保养记录修改成功"})
